<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>MVT: Mapbox Vector Tiles</title>
</head>

<body>

<h1>MVT: Mapbox Vector Tiles</h1>

<p>Starting with GDAL 2.3, the MVT driver can read and write Mapbox Vector Tile files,
as standalone files, uncompressed or gzip-compressed (typical extensions are
.pbf, .mvt, .mvt.gz), or a tileset at a given zoom level of such files.
Write support requires GDAL to be built with libsqlite3 and GEOS support.</p>

<p>Mapbox Vector Tiles stored within a SQLite container conforming to the
MBTiles format are handled by the <a href="frmt_mbtiles.html">MBTiles</a> driver.</p>

<p>Tilesets of MVT files can for example be generated by
<a href="https://github.com/mapbox/tippecanoe">tippecanoe</a> or
<a href="https://github.com/klokantech/tileserver-gl">tileserver-gl</a>. The output
file hierarchy will contain a <a href=#metadata_json>metadata.json</a>
file at its root and {z}/{x}/{y}.pbf files with the tiles, where z is the
zoom level and (x, y) the coordinate of the tile in a given zoom level.
The origin of the tiling system is the top-left tile(XYZ convention).
For example, for zoom levels 0 and 1 :</p>

<pre>
/metadata.json
/0/
   0/
     0.pbf
/1/
   0/
     0.pbf
     1.pbf
   1/
     0.pbf
     1.pbf
</pre>

<p>The driver will assume by default EPSG:3857 (WebMercator) spatial reference system and
Z/X/Y tiling structure, if opening a filename with {Z}/{X}/{Y}.pbf or
{Z}-{X}-{Y}.pbf name, or a zoom level of a tileset. Otherwise integer coordinates
will be reported.</p>

<p>Note: When opening a zoom level of a tileset, the driver will make no effort of
stiching together geometries for features that overlap several tiles.</p>

<h2>Connection strings</h2>

<p>The following connection strings are supported:</p>

<ul>
<li><i>/path/to/some.pbf</i></li>
<li><i>MVT:http[s]://path/to/some.pbf</i></li>
<li><i>/path/to/{Z}</i>: where {Z} is a zoom level between 0 and 30,
tiles are in /path/to/{Z}/{X}/{Y}.pbf files, and /path/to/metadata.json
or /path/to.json should typically exist.</li>
<li><i>MVT:http[s]://path/to/{Z]</i></li>
</ul>

<p>The MVT: prefix may be added before the filename or directory name to help
forcing identification of datasets in some rare cases where non-guided
identification would fail.</p>

<h2 id="metadata_json">metadata.json</h2>

<p>This file is typically generated by tippecanoe and has the following
content:</p>

<pre>
{
    "name": "my_layername",
    "description": "my_layername",
    "version": "2",
    "minzoom": "0",
    "maxzoom": "0",
    "center": "2.500000,49.500000,0",
    "bounds": "2.000000,49.000000,3.000000,50.000000",
    "type": "overlay",
    "format": "pbf",
    "json": "{
        \"vector_layers\": [ {
            \"id\": \"my_layername\",
            \"description\": \"\",
            \"minzoom\": 0,
            \"maxzoom\": 0,
            \"fields\": {
                \"bool_false\": \"Boolean\",
                \"bool_true\": \"Boolean\",
                \"float_value\": \"Number\",
                \"pos_int_value\": \"Number\",
                \"pos_int64_value\": \"Number\",
                \"neg_int_value\": \"Number\",
                \"neg_int64_value\": \"Number\",
                \"pos_sint_value\": \"Number\",
                \"pos_sint64_value\": \"Number\",
                \"neg_sint_value\": \"Number\",
                \"neg_sint64_value\": \"Number\",
                \"real_value\": \"Number\",
                \"string_value\": \"String\",
                \"uint_value\": \"Number\",
                \"uint64_value\": \"Number\"
            }
        } ],
        \"tilestats\": {
            \"layerCount\": 1,
            \"layers\": [
                {
                \"layer\": \"my_layername\",
                \"count\": 2,
                \"geometry\": \"Point\",
                \"attributeCount\": 0,
                \"attributes\": []
                }
            ]
        }
    }}"
}
</pre>

<p>The MVT driver only uses the "json" key to retrieve the layer names,
their fields and the geometry type, and the "bounds" key for the layer extent.
</p>

<p>If this file cannot be found, the layer schema is established by
scanning the features of the tile(s).</p>

<p>As an extension, OGR handles in reading and writing custom tiling schemes
by using the <i>crs</i>, <i>tile_origin_upper_left_x</i>, <i>tile_origin_upper_left_y</i>
and <i>tile_dimension_zoom_0</i> metadata items. For example, for the
Finnish ETRS-TM35FIN (EPSG:3067) tiling scheme:
<pre>
{
 ...
  "crs":"EPSG:3067",
  "tile_origin_upper_left_x":-548576.0,
  "tile_origin_upper_left_y":8388608.0,
  "tile_dimension_zoom_0":2097152.0,
}
</pre>

<h2>Opening options</h2>

The following open options are available:
<ul>
<li><b>X</b>=int_value: X coordinate of the EPSG:3857 tile.</li>
<li><b>Y</b>=int_value: Y coordinate of the EPSG:3857 tile.</li>
<li><b>Z</b>=int_value: Z coordinate of the EPSG:3857 tile.</li>
<li><b>METADATA_FILE</b>=filename: Filename of a metadata.json-like file.
If opening a /path/to/{Z}/{X}/{Y}.pbf file, the driver will by default try to
find /path/to/metadata.json. Setting the value to the empty string is a way
of avoid the metadata.json file to be used.</li>
<li><b>CLIP</b>=YES/NO: Whether to clip geometries of vector features to tile extent.
Generators of vector files will typically create geometries with a small buffer
beyond the tile extent so that geometries intersecting several tiles can be
unioned back. Defaults to YES so that that buffer is removed and geometries are
clipped exactly to the tile extent.</li>
<li><b>TILE_EXTENSION</b>=string: For tilesets, extension of tiles. Defaults
to pbf.</li>
<li><b>TILE_COUNT_TO_ESTABLISH_FEATURE_DEFN</b>=int_value: For tilesets without
metadata file, maximum number of tiles to use to establish the layer schemas.
Defaults to 1000.</li>
<lib><b>JSON_FIELD</b>=YES/NO: For tilesets, whether to put all attributes as a
serialized JSon dictionary.</li>
</ul>

<h2>Creation issues</h2>

<p>Tiles are generated with WebMercator (EPSG:3857) projection by default (
custom tiling schemes can be defined with the TILING_SCHEME option).
Several layers can be written. It is possible to decide at which zoom level ranges a given
layer is written.</p>

<p>Part of the conversion is multi-threaded by default, using as many threads
as they are cores. The number of threads used can be controlled with the
GDAL_NUM_THREADS configuration option.</p>

<h2>Dataset creation options</h2>

<ul>
<li><b>NAME</b>=string: Tileset name. Defaults to the basename of the output
file/directory. Used to fill metadata records.</li>
<li><b>DESCRIPTION</b>=string: A description of the tileset. Used to fill
metadata records.</li>
<li><b>TYPE</b>=overlay/baselayer: Layer type. Used to fill metadata records.</li>
<li><b>FORMAT</b>=DIRECTORY/MBTILES: Format into which tiles are written.
DIRECTORY means that tiles are written in a hierarchy like out_dir/{z}/{x}/{y}.pbf.
MBTILES is for a MBTILES container. Defaults to DIRECTORY, unless the output
filename has a .mbtiles extension</li>
<li><b>TILE_EXTENSION</b>=string: For tilesets as directories of files,
extension of tiles. Defaults to pbf.</li>
<li><b>MINZOOM</b>=integer: Minimum zoom level at which tiles are generated. Defaults
to 0.</li>
<li><b>MAXZOOM</b>=integer: Minimum zoom level at which tiles are generated. Defaults
to 5. Maximum supported value is 22</li>
<li><b>CONF</b>=string: Layer configuration as a JSon serialized string.</li>
<li><b>SIMPLIFICATION</b>=float: Simplification factor for linear or polygonal
geometries. The unit is the integer unit of tiles after quantification of
geometry coordinates to tile coordinates. Applies to all zoom levels,
unless SIMPLIFICATION_MAX_ZOOM is also defined.</li>
<li><b>SIMPLIFICATION_MAX_ZOOM</b>=float: Simplification factor for linear or polygonal
geometries, that applies only for the maximum zoom level.</li>
<li><b>EXTENT</b>=positive_integer. Number of units in a tile. The greater, the
more accurate geometry coordinates (at the expense of tile byte size).
Defaults to 4096</li>
<li><b>BUFFER</b>=positive_integer. Number of units for geometry buffering. This
value corresponds to a buffer around each side of a tile into which geometries are
fetched and clipped. This is used for proper rendering of geometries that spread
over tile boundaries by some rendering clients. Defaults to 80 if EXTENT=4096.</li>
<li><b>COMPRESS</b>=YES/NO. Whether to compress tiles with the Deflate/GZip
algorithm. Defaults to YES. Should be left to YES for FORMAT=MBTILES.</li>
<li><b>TEMPORARY_DB</b>=string. Filename with path for the temporary database used
for tile generation. By default, this will be a file in the same directory as
the output file/directory.</li>
<li><b>MAX_SIZE</b>=integer. Maximum size of a tile in bytes (after compression).
Defaults to 500 000. If a tile is greater than this threshold, features will be
written with reduced precision, or discarded.</li>
<li><b>MAX_FEATURES</b>=integer. Maximum number of features per tile. Defaults
to 200 000.</li>
<li><b>BOUNDS</b>=min_long,min_lat,max_long,max_lat. Override default value for
bounds metadata item which is computed from the extent of features written.</li>
<li><b>CENTER</b>=long,lat,zoom_level. Override default value for center
metadata item, which is the center of BOUNDS at minimum zoom level.</li>
<li><b>TILING_SCHEME</b>=crs,tile_origin_upper_left_x,tile_origin_upper_left_y,
tile_dimension_zoom_0: Define a custom tiling scheme with a CRS (typically
given as EPSG:XXXX), the coordinates of the upper-left corner of the upper-left
tile (0,0) in the CRS, and the dimension of the tile at zoom level 0.
Only available for FORMAT=DIRECTORY.
The standard WebMercator tiling scheme would be defined by
"EPSG:3857,-20037508.343,20037508.343,40075016.686".
A tiling scheme for WGS84 geodetic could be "EPSG:4326,-180,180,360".
The tiling scheme for Finnish ETRS-TM35FIN (EPSG:3067) is
"EPSG:3067,-548576,8388608,2097152".
When using such as custom tiling scheme, the 'crs', 'tile_origin_upper_left_x',
'tile_origin_upper_left_y' and 'tile_dimension_zoom_0' entries are added to
the metadata.json, and are honoured by the OGR MVT reader.
</li>
</ul>

<h2>Layer configuration</h2>

<p>
The above mentioned CONF dataset creation option can be set to a string whose
value is a JSon serialized document such as the below one:
</p>

<pre>
        {
            "boundaries_lod0": {
                "target_name": "boundaries",
                "description": "Country boundaries",
                "minzoom": 0,
                "maxzoom": 2
            },
            "boundaries_lod1": {
                "target_name": "boundaries",
                "minzoom": 3,
                "maxzoom": 5
            }
        }
</pre>

<p>
<i>boundaries_lod0</i> and <i>boundaries_lod1</i> are the name of the OGR
layers that are created into the target MVT dataset. They are mapped to
the MVT target layer <i>boundaries</i>.
</p>

<p>It is also possible to get the same behaviour with the below layer creation
options, although that is not convenient in the ogr2ogr use case.</p>

<h2>Layer creation options</h2>

<ul>
<li><b>MINZOOM</b>=integer: Minimum zoom level at which tiles are generated. Defaults
to the dataset creation option MINZOOM value.</li>
<li><b>MAXZOOM</b>=integer: Minimum zoom level at which tiles are generated. Defaults
to the dataset creation option MAXZOOM value. Maximum supported value is 22</li>
<li><b>NAME</b>=string: Target layer name. Defaults to the layer name, but can
be overridden so that several OGR layers map to a single target MVT layer.
The typical use case is to have different OGR layers for mutually exclusive
zoom level ranges.</li>
<li><b>DESCRIPTION</b>=string: A description of the layer.</li>
</ul>
  
<h2>Examples</h2>

<pre>
ogrinfo MVT:https://free.tilehosting.com/data/v3/1 -oo tile_extension="pbf.pict?key=${YOUR_KEY}" --debug on -oo metadata_file="https://free.tilehosting.com/data/v3.json?key=${YOUR_KEY}"
</pre>

<pre>
ogr2ogr -f MVT mytileset source.gpkg -dsco MAXZOOM=10
</pre>

<p>See Also:</p>

<ul>
<li><a href="https://github.com/mapbox/vector-tile-spec">
Mapbox Vector Tile Specification</a></li>
<li><a href="frmt_mbtiles.html">MBTiles</a> driver</li>
<li><a href="https://github.com/mapbox/tippecanoe">tippecanoe</a>:
Builds vector tilesets from large (or small) collections of GeoJSON, Geobuf,
or CSV features</li>
<li><a href="https://github.com/mapbox/awesome-vector-tiles">Links to tools
dealing with Mapbox Vector Tiles</a></li>
</ul>

</body>
</html>
